/*
*Copyright 2021-2023 NERCIS
*
*Licensed under the Apache License, Version 2.0 (the "License");
*you may not use this file except in compliance with the License.
*You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing, software
*distributed under the License is distributed on an "AS IS" BASIS,
*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*See the License for the specific language governing permissions and
*limitations under the License.
*/

package cn.ac.nercis.pes.community.controller.evaluation.prepare;

import cn.ac.nercis.pes.common.constant.common.AssetConstants;
import cn.ac.nercis.pes.common.constant.common.BaseConstants;
import cn.ac.nercis.pes.common.constant.excel.AssetExcelSheet;
import cn.ac.nercis.pes.common.constant.project.FinishState;
import cn.ac.nercis.pes.community.component.cells.AutoWrapTableCell;
import cn.ac.nercis.pes.community.component.cells.ValidResultTableCell;
import cn.ac.nercis.pes.community.component.controls.MenuListCell;
import cn.ac.nercis.pes.community.component.dialog.MessageDialog;
import cn.ac.nercis.pes.community.component.dialog.MessageType;
import cn.ac.nercis.pes.community.component.dialog.PageDialog;
import cn.ac.nercis.pes.community.component.dialog.SpinnerDialog;
import cn.ac.nercis.pes.community.model.vo.MenuVO;
import cn.ac.nercis.pes.community.support.event.CommonCallback;
import cn.ac.nercis.pes.community.utils.ControlUtils;
import cn.ac.nercis.pes.community.utils.SpringUtils;
import cn.ac.nercis.pes.model.bo.excel.AssetExcelBO;
import cn.ac.nercis.pes.model.bo.excel.asset.*;
import cn.ac.nercis.pes.service.evaluation.AssetImportService;
import com.alibaba.excel.util.StringUtils;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;

import java.io.File;
import java.net.URL;
import java.util.Objects;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 资产对象导入管理控制器
 * @author zpy
 * @version 1.0.0
 */
@Slf4j
public class AssetImportController implements Initializable {
    @FXML
    private Label titleLbl;
    @FXML
    private ListView<MenuVO> menuListView;
    @FXML
    private HBox assetBody;
    @FXML
    private AnchorPane emptyPane;
    @FXML
    private ImageView emptyImageView;
    @FXML
    private Label emptyLabel;
    @FXML
    private Button importBtn;
    @FXML
    private Button cancelBtn;
    @FXML
    private TableView<BaseExcelBO> tableView;

    @FXML
    private HBox globalReplaceBox;
    @FXML
    private ToggleGroup replaceGroup;
    @FXML
    private RadioButton allReplaceRbx;
    @FXML
    private HBox assetRepeatBody;
    @FXML
    private ListView<MenuVO> repeatSheetListView;
    @FXML
    private GridPane assetRepeatGrid;

    private final AssetImportService assetImportService;
    private File excelFile;
    private PageDialog pageDialog;
    private CommonCallback successCall;
    private AssetExcelBO excelData;
    private AssetExcelBO repeatExcelData;
    private Mode importMode = Mode.IMPORT;
    private StackPane page;
    private String currentSystemId;

    public AssetImportController() {
        this.assetImportService = SpringUtils.getBean(AssetImportService.class);
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        menuListView.setCellFactory(listView -> new MenuListCell());
        repeatSheetListView.setCellFactory(listView -> new MenuListCell());
        menuListView.getSelectionModel()
                .selectedItemProperty()
                .addListener((observable,oldValue,newValue)-> {
                    if(Objects.nonNull(newValue)){
                        loadCheckData(newValue);
                    }
                });
        repeatSheetListView.getSelectionModel()
                .selectedItemProperty()
                .addListener((observable,oldValue,newValue)->{
                    if(Objects.nonNull(newValue)){
                        loadRepeatData(newValue);
                    }
                });
        assetBody.managedProperty().bind(assetBody.visibleProperty());
        assetRepeatBody.managedProperty().bind(assetRepeatBody.visibleProperty());
        ClassPathResource emptyImageResource = new ClassPathResource("images/evaluation/empty.png");
        try {
            this.emptyImageView.setImage(new Image(emptyImageResource.getInputStream()));
        }catch (Exception ex){
            log.error("加载空图片失败",ex);
        }
    }

    public void initializeData(String systemId,File excelFile,PageDialog pageDialog,CommonCallback successCall){
        this.excelFile = excelFile;
        this.pageDialog = pageDialog;
        this.successCall = successCall;
        this.importMode = Mode.IMPORT;
        this.currentSystemId = systemId;
        this.page = pageDialog.getDialogContainer();
        this.checkImportData();
    }

    @FXML
    public void onImport(){
        if(importMode == Mode.IMPORT){
            importAssetData();
        }else {
            coverAssetData();
        }
    }

    @FXML
    public void onClose(){
        this.pageDialog.close();
    }

    private void importAssetData(){
        SpinnerDialog spinnerDialog =  SpinnerDialog.builder()
                .withProcessTip("正在导入的资产对象信息中...")
                .withContainer(Objects.requireNonNull(this.page))
                .build();
        spinnerDialog.show();
        CompletableFuture.supplyAsync(()->assetImportService.importAssetData(this.currentSystemId, excelData))
                .thenAccept(res-> Platform.runLater(()->{
                    spinnerDialog.close();
                    if(res.isSuccess()){
                        repeatExcelData = res.getData();
                        if(repeatExcelData.isEmpty()){
                            MessageDialog.builder()
                                    .withContainer(Objects.requireNonNull(this.page))
                                    .withType(MessageType.SUCCESS).withMessage("导入成功")
                                    .build().show();
                            this.pageDialog.close();
                            if(Objects.nonNull(successCall)){
                                successCall.action();
                            }
                        }else{
                            initCoverMode();
                        }
                    }else{
                        MessageDialog.builder()
                                .withContainer(Objects.requireNonNull(this.page))
                                .withType(MessageType.FAIL).withMessage(res.getMsg())
                                .build().show();
                        this.importBtn.setVisible(false);
                    }
                }))
                .exceptionally((ex) -> {
                    spinnerDialog.close();
                    log.error("导入资产对象信息出错!", ex);
                    MessageDialog.builder()
                            .withContainer(Objects.requireNonNull(this.page))
                            .withType(MessageType.FAIL).withMessage("导入资产对象信息出错!")
                            .build().show();
                    return null;
                });
    }

    private void coverAssetData(){
        String text = ((RadioButton)replaceGroup.getSelectedToggle()).getText();
        repeatExcelData.setGlobalCover(StringUtils.equals(text,allReplaceRbx.getText()));
        SpinnerDialog spinnerDialog =  SpinnerDialog.builder()
                .withProcessTip("正在导入资产对象信息...")
                .withContainer(Objects.requireNonNull(this.page))
                .build();
        spinnerDialog.show();
        CompletableFuture.supplyAsync(()->assetImportService.coverAssetData(this.currentSystemId, repeatExcelData))
                .thenAccept(res-> Platform.runLater(()->{
                    spinnerDialog.close();
                    if(res.isSuccess()){
                        MessageDialog.builder()
                                .withContainer(Objects.requireNonNull(this.page))
                                .withType(MessageType.SUCCESS).withMessage("导入成功")
                                .build().show();
                        this.pageDialog.close();
                        if(Objects.nonNull(successCall)){
                            successCall.action();
                        }
                    }else{
                        MessageDialog.builder()
                                .withContainer(Objects.requireNonNull(this.page))
                                .withType(MessageType.FAIL).withMessage(res.getMsg())
                                .build().show();
                        this.importBtn.setVisible(false);
                    }
                }))
                .exceptionally((ex) -> {
                    spinnerDialog.close();
                    log.error("导入资产对象信息（覆盖操作）出错!", ex);
                    MessageDialog.builder()
                            .withContainer(Objects.requireNonNull(this.page))
                            .withType(MessageType.FAIL).withMessage("导入资产对象信息出错!")
                            .build().show();
                    return null;
                });
    }

    private void initCoverMode(){
        this.importMode = Mode.COVER;
        this.titleLbl.setText("替换或跳过资产对象");
        this.assetBody.setVisible(false);
        this.assetRepeatBody.setVisible(true);
        this.globalReplaceBox.setVisible(true);

        repeatSheetListView.getItems().clear();
        repeatExcelData.findAllSheet().forEach(sheet->{
            repeatSheetListView.getItems().add(new MenuVO(0,"",sheet,"","none-process",""));
        });
        repeatSheetListView.getSelectionModel().select(0);
    }

    private void checkImportData(){
        SpinnerDialog spinnerDialog =  SpinnerDialog.builder()
                .withProcessTip("正在读取并检查导入的资产对象信息...")
                .withContainer(Objects.requireNonNull(this.page))
                .build();
        spinnerDialog.show();
        CompletableFuture.supplyAsync(()->assetImportService.checkImportData(excelFile))
                .thenAccept(res-> Platform.runLater(()->{
                    spinnerDialog.close();
                    if(res.isSuccess()){
                        if(res.getData().isEmpty()){
                            this.assetBody.setVisible(false);
                            this.emptyPane.setVisible(true);
                            this.emptyLabel.setText("导入的文档无资产对象信息");
                            this.importBtn.setVisible(false);
                        }else{
                            this.assetBody.setVisible(true);
                            this.emptyPane.setVisible(false);
                            loadMenuData(res.getData());
                            this.importBtn.setVisible(!res.getData().hasValidFailed());
                        }
                    }else{
                        pageDialog.close();
                        MessageDialog.builder()
                                .withContainer(Objects.requireNonNull(this.page))
                                .withType(MessageType.FAIL).withMessage(res.getMsg())
                                .build().show();
                    }
                }))
                .exceptionally((ex) -> {
                    spinnerDialog.close();
                    log.error("检查导入的资产对象信息出错!", ex);
                    MessageDialog.builder()
                            .withContainer(Objects.requireNonNull(this.page))
                            .withType(MessageType.FAIL).withMessage("检查导入的资产对象信息出错!")
                            .build().show();
                    return null;
                });
    }

    private void loadMenuData(@NonNull AssetExcelBO data){
        excelData = data;
        menuListView.getItems().clear();
        data.findAllSheet().forEach(sheet->{
            MenuVO menuVO = new MenuVO(0,"",sheet,"");
            menuVO.setError(excelData.hasValidFailed(sheet));
            if(excelData.hasValidFailed(sheet)){
                menuVO.setIcon(ControlUtils.finishStateToIcon(FinishState.INCOMPLETE));
                menuVO.setCssStyle("error-process");
                menuVO.setToolTip("存在验证失败的数据");
            }else{
                menuVO.setIcon(ControlUtils.finishStateToIcon(FinishState.FINISH));
                menuVO.setCssStyle("none-process");
            }
            menuListView.getItems().add(menuVO);
        });
        menuListView.getSelectionModel().select(0);
    }

    private void loadCheckData(@NonNull MenuVO menuLabel){
        tableView.getItems().clear();
        tableView.getColumns().clear();
        AssetExcelSheet sheet = AssetExcelSheet.fromName(menuLabel.getTitle());
        switch (sheet) {
            case PHY_ENV -> initPhyEnvTable();
            case PHY_SECURITY -> initPhySecurityTable();
            case PWD_PRODUCT -> initPwdProductTable();
            case SERVER_STORAGE -> initServerStorageTable();
            case NETWORK_SECURITY -> initNetworkSecurityTable();
            case DATABASE -> initDatabaseTable();
            case KEY_BUSINESS -> initKeyBusinessTable();
            case SUB_BUSINESS -> initSubBusinessTable();
            case KEY_DATA -> initKeyDataTable();
            case SECURITY_DOC -> initSecurityDocumentTable();
            case PERSONNEL -> initPersonnelTable();
        }
        tableView.refresh();
    }

    private void initPhyEnvTable(){
        tableView.getColumns().add(getExcelRowColumn());
        TableColumn<BaseExcelBO,String> nameColumn = new TableColumn<>("*物理环境名称");
        nameColumn.setSortable(false);
        nameColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PhyEnvBO)cellData.getValue()).getName()));
        nameColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> locationColumn = new TableColumn<>("*物理位置");
        locationColumn.setSortable(false);
        locationColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PhyEnvBO)cellData.getValue()).getLocation()));
        locationColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> importanceColumn = new TableColumn<>("*重要程度");
        importanceColumn.setSortable(false);
        importanceColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PhyEnvBO)cellData.getValue()).getImportance()));
        importanceColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> descColumn = new TableColumn<>("备注");
        descColumn.setSortable(false);
        descColumn.setCellValueFactory(cellData->{
            String value = ((PhyEnvBO)cellData.getValue()).getDesc();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        descColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());


        tableView.getColumns().addAll(nameColumn,locationColumn,importanceColumn,descColumn,
                getResultColumn(),getValidMsgColumn());

        tableView.setItems(new SimpleListProperty<>(FXCollections.observableArrayList(excelData.getPhyEnvs())));
    }

    private void initPhySecurityTable(){
        tableView.getColumns().add(getExcelRowColumn());
        TableColumn<BaseExcelBO,String> nameColumn = new TableColumn<>("*产品名称");
        nameColumn.setSortable(false);
        nameColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PhySecurityBO)cellData.getValue()).getName()));
        nameColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> vendorColumn = new TableColumn<>("生产厂商和型号");
        vendorColumn.setSortable(false);
        vendorColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PhySecurityBO)cellData.getValue()).getVendor()));
        vendorColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> locationColumn = new TableColumn<>("*所在物理环境名称");
        locationColumn.setSortable(false);
        locationColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PhySecurityBO)cellData.getValue()).getLocation()));
        locationColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> requireColumn = new TableColumn<>("*安全需求");
        requireColumn.setSortable(false);
        requireColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PhySecurityBO)cellData.getValue()).getRequire()));
        requireColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> importanceColumn = new TableColumn<>("*重要程度");
        importanceColumn.setSortable(false);
        importanceColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PhySecurityBO)cellData.getValue()).getImportance()));
        importanceColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> isUseColumn = new TableColumn<>("是否测评");
        isUseColumn.setSortable(false);
        isUseColumn.setCellValueFactory(cellData->{
            String value = ((PhySecurityBO)cellData.getValue()).getIsUse();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        isUseColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> descColumn = new TableColumn<>("备注");
        descColumn.setSortable(false);
        descColumn.setCellValueFactory(cellData->{
            String value = ((PhySecurityBO)cellData.getValue()).getDesc();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        descColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());
        tableView.getColumns().addAll(nameColumn,vendorColumn,locationColumn,requireColumn,importanceColumn,isUseColumn,descColumn,
                getResultColumn(),getValidMsgColumn());

        tableView.setItems(new SimpleListProperty<>(FXCollections.observableArrayList(excelData.getPhySecurity())));
    }

    private void initPwdProductTable(){
        tableView.getColumns().add(getExcelRowColumn());
        TableColumn<BaseExcelBO,String> nameColumn = new TableColumn<>("*产品名称");
        nameColumn.setSortable(false);
        nameColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PwdProductBO)cellData.getValue()).getName()));
        nameColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> vendorColumn = new TableColumn<>("生产厂商");
        vendorColumn.setSortable(false);
        vendorColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PwdProductBO)cellData.getValue()).getVendor()));
        vendorColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> modelColumn = new TableColumn<>("*商密产品认证证书编号");
        modelColumn.setSortable(false);
        modelColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PwdProductBO)cellData.getValue()).getModel()));
        modelColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> algorithmColumn = new TableColumn<>("*使用的密码算法");
        algorithmColumn.setSortable(false);
        algorithmColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PwdProductBO)cellData.getValue()).getAlgorithm()));
        algorithmColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> countColumn = new TableColumn<>("数量");
        countColumn.setSortable(false);
        countColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PwdProductBO)cellData.getValue()).getCount()));
        countColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> useColumn = new TableColumn<>("数量");
        useColumn.setSortable(false);
        useColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PwdProductBO)cellData.getValue()).getUse()));
        useColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> isUseColumn = new TableColumn<>("是否测评");
        isUseColumn.setSortable(false);
        isUseColumn.setCellValueFactory(cellData->{
            String value = ((PwdProductBO)cellData.getValue()).getIsUse();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        isUseColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> descColumn = new TableColumn<>("备注");
        descColumn.setSortable(false);
        descColumn.setCellValueFactory(cellData->{
            String value = ((PwdProductBO)cellData.getValue()).getDesc();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        descColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        tableView.getColumns().addAll(nameColumn,vendorColumn,modelColumn,algorithmColumn,countColumn,useColumn,isUseColumn,descColumn,
                getResultColumn(),getValidMsgColumn());

        tableView.setItems(new SimpleListProperty<>(FXCollections.observableArrayList(excelData.getPwdProducts())));
    }

    private void initServerStorageTable(){
        tableView.getColumns().add(getExcelRowColumn());
        TableColumn<BaseExcelBO,String> nameColumn = new TableColumn<>("*设备名称");
        nameColumn.setSortable(false);
        nameColumn.setCellValueFactory(cellData->new SimpleStringProperty(((ServerStorageBO)cellData.getValue()).getName()));
        nameColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> vendorColumn = new TableColumn<>("生产厂商");
        vendorColumn.setSortable(false);
        vendorColumn.setCellValueFactory(cellData->new SimpleStringProperty(((ServerStorageBO)cellData.getValue()).getVendor()));
        vendorColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> modelColumn = new TableColumn<>("型号");
        modelColumn.setSortable(false);
        modelColumn.setCellValueFactory(cellData->new SimpleStringProperty(((ServerStorageBO)cellData.getValue()).getModel()));
        modelColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> osNameColumn = new TableColumn<>("操作系统版本");
        osNameColumn.setSortable(false);
        osNameColumn.setCellValueFactory(cellData->new SimpleStringProperty(((ServerStorageBO)cellData.getValue()).getOsName()));
        osNameColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> virtualColumn = new TableColumn<>("是否为虚拟设备");
        virtualColumn.setSortable(false);
        virtualColumn.setCellValueFactory(cellData->new SimpleStringProperty(((ServerStorageBO)cellData.getValue()).getVirtual()));
        virtualColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> useColumn = new TableColumn<>("用途");
        useColumn.setSortable(false);
        useColumn.setCellValueFactory(cellData->new SimpleStringProperty(((ServerStorageBO)cellData.getValue()).getUse()));
        useColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> countColumn = new TableColumn<>("*数量");
        countColumn.setSortable(false);
        countColumn.setCellValueFactory(cellData->new SimpleStringProperty(((ServerStorageBO)cellData.getValue()).getCount()));
        countColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> importanceColumn = new TableColumn<>("*重要程度");
        importanceColumn.setSortable(false);
        importanceColumn.setCellValueFactory(cellData->new SimpleStringProperty(((ServerStorageBO)cellData.getValue()).getImportance()));
        importanceColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> isUseColumn = new TableColumn<>("是否测评");
        isUseColumn.setSortable(false);
        isUseColumn.setCellValueFactory(cellData->{
            String value = ((ServerStorageBO)cellData.getValue()).getIsUse();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        isUseColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> descColumn = new TableColumn<>("备注");
        descColumn.setSortable(false);
        descColumn.setCellValueFactory(cellData->{
            String value = ((ServerStorageBO)cellData.getValue()).getDesc();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        descColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        tableView.getColumns().addAll(nameColumn,vendorColumn,modelColumn,osNameColumn,virtualColumn,useColumn,countColumn,importanceColumn,isUseColumn,descColumn,
                getResultColumn(),getValidMsgColumn());

        tableView.setItems(new SimpleListProperty<>(FXCollections.observableArrayList(excelData.getServerStorages())));
    }

    private void initNetworkSecurityTable(){
        tableView.getColumns().add(getExcelRowColumn());
        TableColumn<BaseExcelBO,String> nameColumn = new TableColumn<>("*设备名称");
        nameColumn.setSortable(false);
        nameColumn.setCellValueFactory(cellData->new SimpleStringProperty(((NetworkSecurityBO)cellData.getValue()).getName()));
        nameColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> vendorColumn = new TableColumn<>("*生产厂商");
        vendorColumn.setSortable(false);
        vendorColumn.setCellValueFactory(cellData->new SimpleStringProperty(((NetworkSecurityBO)cellData.getValue()).getVendor()));
        vendorColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> modelColumn = new TableColumn<>("型号");
        modelColumn.setSortable(false);
        modelColumn.setCellValueFactory(cellData->new SimpleStringProperty(((NetworkSecurityBO)cellData.getValue()).getModel()));
        modelColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> useColumn = new TableColumn<>("用途（包括涉及的密码技术）");
        useColumn.setSortable(false);
        useColumn.setCellValueFactory(cellData->new SimpleStringProperty(((NetworkSecurityBO)cellData.getValue()).getUse()));
        useColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> countColumn = new TableColumn<>("*数量");
        countColumn.setSortable(false);
        countColumn.setCellValueFactory(cellData->new SimpleStringProperty(((NetworkSecurityBO)cellData.getValue()).getCount()));
        countColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> importanceColumn = new TableColumn<>("*重要程度");
        importanceColumn.setSortable(false);
        importanceColumn.setCellValueFactory(cellData->new SimpleStringProperty(((NetworkSecurityBO)cellData.getValue()).getImportance()));
        importanceColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> isUseColumn = new TableColumn<>("是否测评");
        isUseColumn.setSortable(false);
        isUseColumn.setCellValueFactory(cellData->{
            String value = ((NetworkSecurityBO)cellData.getValue()).getIsUse();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        isUseColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> descColumn = new TableColumn<>("备注");
        descColumn.setSortable(false);
        descColumn.setCellValueFactory(cellData->{
            String value = ((NetworkSecurityBO)cellData.getValue()).getDesc();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        descColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        tableView.getColumns().addAll(nameColumn,vendorColumn,modelColumn,useColumn,countColumn,importanceColumn,isUseColumn,descColumn,
                getResultColumn(),getValidMsgColumn());

        tableView.setItems(new SimpleListProperty<>(FXCollections.observableArrayList(excelData.getNetworkSecurity())));
    }

    private void initDatabaseTable(){
        tableView.getColumns().add(getExcelRowColumn());
        TableColumn<BaseExcelBO,String> nameColumn = new TableColumn<>("*数据库管理系统名称");
        nameColumn.setSortable(false);
        nameColumn.setCellValueFactory(cellData->new SimpleStringProperty(((DatabaseBO)cellData.getValue()).getName()));
        nameColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> vendorColumn = new TableColumn<>("*版本");
        vendorColumn.setSortable(false);
        vendorColumn.setCellValueFactory(cellData->new SimpleStringProperty(((DatabaseBO)cellData.getValue()).getVersion()));
        vendorColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> modelColumn = new TableColumn<>("*部署位置");
        modelColumn.setSortable(false);
        modelColumn.setCellValueFactory(cellData->new SimpleStringProperty(((DatabaseBO)cellData.getValue()).getLocation()));
        modelColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> functionColumn = new TableColumn<>("主要功能");
        functionColumn.setSortable(false);
        functionColumn.setCellValueFactory(cellData->new SimpleStringProperty(((DatabaseBO)cellData.getValue()).getFunction()));
        functionColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> importanceColumn = new TableColumn<>("*重要程度");
        importanceColumn.setSortable(false);
        importanceColumn.setCellValueFactory(cellData->new SimpleStringProperty(((DatabaseBO)cellData.getValue()).getImportance()));
        importanceColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> isUseColumn = new TableColumn<>("是否测评");
        isUseColumn.setSortable(false);
        isUseColumn.setCellValueFactory(cellData->{
            String value = ((DatabaseBO)cellData.getValue()).getIsUse();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        isUseColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> descColumn = new TableColumn<>("备注");
        descColumn.setSortable(false);
        descColumn.setCellValueFactory(cellData->{
            String value = ((DatabaseBO)cellData.getValue()).getDesc();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        descColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        tableView.getColumns().addAll(nameColumn,vendorColumn,modelColumn,functionColumn,importanceColumn,isUseColumn,descColumn,
                getResultColumn(),getValidMsgColumn());

        tableView.setItems(new SimpleListProperty<>(FXCollections.observableArrayList(excelData.getDatabases())));
    }

    private void initKeyBusinessTable(){
        tableView.getColumns().add(getExcelRowColumn());
        TableColumn<BaseExcelBO,String> nameColumn = new TableColumn<>("*应用名称");
        nameColumn.setSortable(false);
        nameColumn.setCellValueFactory(cellData->new SimpleStringProperty(((KeyBusinessBO)cellData.getValue()).getName()));
        nameColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> vendorColumn = new TableColumn<>("版本");
        vendorColumn.setSortable(false);
        vendorColumn.setCellValueFactory(cellData->new SimpleStringProperty(((KeyBusinessBO)cellData.getValue()).getVersion()));
        vendorColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> modelColumn = new TableColumn<>("*部署位置");
        modelColumn.setSortable(false);
        modelColumn.setCellValueFactory(cellData->new SimpleStringProperty(((KeyBusinessBO)cellData.getValue()).getLocation()));
        modelColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> functionColumn = new TableColumn<>("主要功能");
        functionColumn.setSortable(false);
        functionColumn.setCellValueFactory(cellData->new SimpleStringProperty(((KeyBusinessBO)cellData.getValue()).getFunction()));
        functionColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> descColumn = new TableColumn<>("备注");
        descColumn.setSortable(false);
        descColumn.setCellValueFactory(cellData->{
            String value = ((KeyBusinessBO)cellData.getValue()).getDesc();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        descColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());
        tableView.getColumns().addAll(nameColumn, vendorColumn, modelColumn, functionColumn, descColumn,
                getResultColumn(), getValidMsgColumn());

        tableView.setItems(new SimpleListProperty<>(FXCollections.observableArrayList(excelData.getKeyBusiness())));
    }

    private void initSubBusinessTable(){
        tableView.getColumns().add(getExcelRowColumn());
        TableColumn<BaseExcelBO,String> dataColumn = new TableColumn<>("*名称");
        dataColumn.setSortable(false);
        dataColumn.setCellValueFactory(cellData->new SimpleStringProperty(((SubBusinessBO)cellData.getValue()).getName()));
        dataColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> ownedAppColumn = new TableColumn<>("*所属应用");
        ownedAppColumn.setSortable(false);
        ownedAppColumn.setCellValueFactory(cellData->new SimpleStringProperty(((SubBusinessBO)cellData.getValue()).getOwnedApp()));
        ownedAppColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> requireColumn = new TableColumn<>("*安全需求");
        requireColumn.setSortable(false);
        requireColumn.setCellValueFactory(cellData->new SimpleStringProperty(((SubBusinessBO)cellData.getValue()).getRequire()));
        requireColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> isUseColumn = new TableColumn<>("是否测评");
        isUseColumn.setSortable(false);
        isUseColumn.setCellValueFactory(cellData->{
            String value = ((SubBusinessBO)cellData.getValue()).getIsUse();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        isUseColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> descColumn = new TableColumn<>("备注");
        descColumn.setSortable(false);
        descColumn.setCellValueFactory(cellData->{
            String value = ((SubBusinessBO)cellData.getValue()).getDesc();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        descColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        tableView.getColumns().addAll(dataColumn,ownedAppColumn,requireColumn,isUseColumn,descColumn,
                getResultColumn(),getValidMsgColumn());

        tableView.setItems(new SimpleListProperty<>(FXCollections.observableArrayList(excelData.getSubBusiness())));
    }

    private void initKeyDataTable(){
        tableView.getColumns().add(getExcelRowColumn());
        TableColumn<BaseExcelBO,String> dataColumn = new TableColumn<>("*数据");
        dataColumn.setSortable(false);
        dataColumn.setCellValueFactory(cellData->new SimpleStringProperty(((KeyDataBO)cellData.getValue()).getData()));
        dataColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> describeColumn = new TableColumn<>("*描述");
        describeColumn.setSortable(false);
        describeColumn.setCellValueFactory(cellData->new SimpleStringProperty(((KeyDataBO)cellData.getValue()).getDescribe()));
        describeColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> ownedAppColumn = new TableColumn<>("*所属应用");
        ownedAppColumn.setSortable(false);
        ownedAppColumn.setCellValueFactory(cellData->new SimpleStringProperty(((KeyDataBO)cellData.getValue()).getOwnedApp()));
        ownedAppColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> locationColumn = new TableColumn<>("存储位置");
        locationColumn.setSortable(false);
        locationColumn.setCellValueFactory(cellData->new SimpleStringProperty(((KeyDataBO)cellData.getValue()).getLocation()));
        locationColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());


        TableColumn<BaseExcelBO,String> requireColumn = new TableColumn<>("*安全需求");
        requireColumn.setSortable(false);
        requireColumn.setCellValueFactory(cellData->new SimpleStringProperty(((KeyDataBO)cellData.getValue()).getRequire()));
        requireColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> descColumn = new TableColumn<>("备注");
        descColumn.setSortable(false);
        descColumn.setCellValueFactory(cellData->{
            String value = ((KeyDataBO)cellData.getValue()).getDesc();
            return new SimpleStringProperty(StringUtils.isEmpty(value)?"":value);
        });
        descColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        tableView.getColumns().addAll(dataColumn,describeColumn,ownedAppColumn,locationColumn,requireColumn,descColumn,
                getResultColumn(),getValidMsgColumn());

        tableView.setItems(new SimpleListProperty<>(FXCollections.observableArrayList(excelData.getKeyData())));
    }

    private void initSecurityDocumentTable(){
        tableView.getColumns().add(getExcelRowColumn());
        TableColumn<BaseExcelBO,String> nameColumn = new TableColumn<>("*文档名称");
        nameColumn.setSortable(false);
        nameColumn.setCellValueFactory(cellData->new SimpleStringProperty(((SecurityDocumentBO)cellData.getValue()).getName()));
        nameColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> contentColumn = new TableColumn<>("*主要内容");
        contentColumn.setSortable(false);
        contentColumn.setCellValueFactory(cellData->new SimpleStringProperty(((SecurityDocumentBO)cellData.getValue()).getContent()));
        contentColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        tableView.getColumns().addAll(nameColumn,contentColumn,getResultColumn(),getValidMsgColumn());

        tableView.setItems(new SimpleListProperty<>(FXCollections.observableArrayList(excelData.getSecurityDocuments())));
    }

    private void initPersonnelTable(){
        tableView.getColumns().add(getExcelRowColumn());
        TableColumn<BaseExcelBO,String> nameColumn = new TableColumn<>("*姓名");
        nameColumn.setSortable(false);
        nameColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PersonnelBO)cellData.getValue()).getName()));
        nameColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> roleColumn = new TableColumn<>("*岗位/角色");
        roleColumn.setSortable(false);
        roleColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PersonnelBO)cellData.getValue()).getRole()));
        roleColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        TableColumn<BaseExcelBO,String> descColumn = new TableColumn<>("*职责说明");
        descColumn.setSortable(false);
        descColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PersonnelBO)cellData.getValue()).getDesc()));
        descColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());


        TableColumn<BaseExcelBO,String> telColumn = new TableColumn<>("*联系方式");
        telColumn.setSortable(false);
        telColumn.setCellValueFactory(cellData->new SimpleStringProperty(((PersonnelBO)cellData.getValue()).getTel()));
        telColumn.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());

        tableView.getColumns().addAll(nameColumn,roleColumn,descColumn,telColumn,
                getResultColumn(),getValidMsgColumn());

        tableView.setItems(new SimpleListProperty<>(FXCollections.observableArrayList(excelData.getPersonnel())));
    }

    private TableColumn<BaseExcelBO,String> getExcelRowColumn(){
        TableColumn<BaseExcelBO,String> column = new TableColumn<>("行号");
        column.setCellValueFactory(cellData-> new SimpleStringProperty(cellData.getValue().getRowNumber().toString()));
        column.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());
        column.setMinWidth(60);
        column.setMaxWidth(60);
        column.setSortable(false);
        return column;
    }

    private TableColumn<BaseExcelBO,Boolean> getResultColumn(){
        TableColumn<BaseExcelBO,Boolean> column = new TableColumn<>("结果");
        column.setCellValueFactory(cellData-> new SimpleBooleanProperty(cellData.getValue().getResult()));
        column.setCellFactory((TableColumn<BaseExcelBO,Boolean> param) ->
                new ValidResultTableCell<>("通过","未通过"));
        column.setMinWidth(80);
        column.setMaxWidth(80);
        column.setSortable(false);
        return column;
    }

    private TableColumn<BaseExcelBO,String> getValidMsgColumn(){
        TableColumn<BaseExcelBO,String> column = new TableColumn<>("失败原因");
        column.setCellValueFactory(cellData-> new SimpleStringProperty(cellData.getValue().getValidMsg()));
        column.setCellFactory((TableColumn<BaseExcelBO,String> param) ->
                new AutoWrapTableCell<>());
        column.setSortable(false);
        return column;
    }

    private void loadRepeatData(@NonNull MenuVO menuLabel){
        assetRepeatGrid.getColumnConstraints().clear();
        assetRepeatGrid.getRowConstraints().clear();
        assetRepeatGrid.getChildren().clear();
        AssetExcelSheet sheet = AssetExcelSheet.fromName(menuLabel.getTitle());
        switch (sheet){
            case PHY_ENV:
                initPhyEnvRepeat();
                break;
            case PHY_SECURITY:
                initPhySecurityRepeat();
                break;
            case PWD_PRODUCT:
                initPwdProductRepeat();
                break;
            case SERVER_STORAGE:
                initServerStorageRepeat();
                break;
            case NETWORK_SECURITY:
                initNetworkSecurityRepeat();
                break;
            case DATABASE:
                initDatabaseRepeat();
                break;
            case KEY_BUSINESS:
                initKeyBusinessRepeat();
                break;
            case SUB_BUSINESS:
                initSubBusinessRepeat();
                break;
            case KEY_DATA:
                initKeyDataRepeat();
                break;
            case SECURITY_DOC:
                initSecurityDocumentRepeat();
                break;
            case PERSONNEL:
                initPersonnelRepeat();
                break;
        }
    }

    private void initPhyEnvRepeat(){
        this.initGridHead(repeatExcelData.getPhyEnvs().size()*2,"重复资产","物理位置","重要程度","是否测评","备注");
        AtomicInteger dataRowIndex = new AtomicInteger(1);
        repeatExcelData.getPhyEnvs().forEach(data->renderPhyEnvRepeat(dataRowIndex,data));
    }
    private void renderPhyEnvRepeat(AtomicInteger rowIndex,PhyEnvBO phyEnvBO){
        AtomicInteger columnIndex = new AtomicInteger(0);
        this.assetRepeatGrid.add(generateDataCell(phyEnvBO.getSource().getName()),
                columnIndex.getAndIncrement(),rowIndex.get(),1,2);
        this.assetRepeatGrid.add(generateDataCell(phyEnvBO.getSource().getLocation()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(phyEnvBO.getSource().getImportance()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(isUseToString(phyEnvBO.getSource().getIsUse())),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(phyEnvBO.getSource().getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("已存在资产"),
                columnIndex.getAndIncrement(),rowIndex.get());
        ChangeListener<Toggle> callback = (observable, oldValue, newValue) -> {
            if(Objects.nonNull(newValue) && newValue instanceof RadioButton radioButton){
                String text = radioButton.getText();
                phyEnvBO.setRepeatCover(StringUtils.equals(text,"覆盖"));
            }
        };
        this.assetRepeatGrid.add(generateOptionCell(phyEnvBO.getRepeatCover(),callback),
                columnIndex.getAndSet(1),rowIndex.getAndIncrement(),1,2);

        this.assetRepeatGrid.add(generateDataCell(phyEnvBO.getLocation()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(phyEnvBO.getImportance()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(phyEnvBO.getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("导入的资产"),
                columnIndex.getAndIncrement(),rowIndex.getAndIncrement());
    }

    private void initPhySecurityRepeat(){
        this.initGridHead(repeatExcelData.getPhySecurity().size()*2,
                "重复资产","生产厂商和型号","所在物理环境名称","重要程度","是否测评","备注");
        AtomicInteger dataRowIndex = new AtomicInteger(1);
        repeatExcelData.getPhySecurity().forEach(data->renderPhySecurityRepeat(dataRowIndex,data));
    }
    private void renderPhySecurityRepeat(AtomicInteger rowIndex,PhySecurityBO data){
        AtomicInteger columnIndex = new AtomicInteger(0);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getName()),
                columnIndex.getAndIncrement(),rowIndex.get(),1,2);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getVendor()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getLocation()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getRequire()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getImportance()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(isUseToString(data.getSource().getIsUse())),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("已存在资产"),
                columnIndex.getAndIncrement(),rowIndex.get());
        ChangeListener<Toggle> callback = (observable, oldValue, newValue) -> {
            if(Objects.nonNull(newValue) && newValue instanceof RadioButton radioButton){
                String text = radioButton.getText();
                data.setRepeatCover(StringUtils.equals(text,"覆盖"));
            }
        };
        this.assetRepeatGrid.add(generateOptionCell(data.getRepeatCover(),callback),
                columnIndex.getAndSet(1),rowIndex.getAndIncrement(),1,2);

        this.assetRepeatGrid.add(generateDataCell(data.getVendor()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getLocation()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getImportance()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getIsUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("导入的资产"),
                columnIndex.getAndIncrement(),rowIndex.getAndIncrement());
    }

    private void initPwdProductRepeat(){
        this.initGridHead(repeatExcelData.getPwdProducts().size()*2,
                "重复资产","生产厂商","商密产品认证证书编号","使用的密码算法","数量","用途","是否测评","备注");
        AtomicInteger dataRowIndex = new AtomicInteger(1);
        repeatExcelData.getPwdProducts().forEach(data->renderPwdProductRepeat(dataRowIndex,data));
    }
    private void renderPwdProductRepeat(AtomicInteger rowIndex,PwdProductBO data){
        AtomicInteger columnIndex = new AtomicInteger(0);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getName()),
                columnIndex.getAndIncrement(),rowIndex.get(),1,2);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getVendor()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getModel()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getAlgorithm()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getCount()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(isUseToString(data.getSource().getIsUse())),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("已存在资产"),
                columnIndex.getAndIncrement(),rowIndex.get());
        ChangeListener<Toggle> callback = (observable, oldValue, newValue) -> {
            if(Objects.nonNull(newValue) && newValue instanceof RadioButton radioButton){
                String text = radioButton.getText();
                data.setRepeatCover(StringUtils.equals(text,"覆盖"));
            }
        };
        this.assetRepeatGrid.add(generateOptionCell(data.getRepeatCover(),callback),
                columnIndex.getAndSet(1),rowIndex.getAndIncrement(),1,2);

        this.assetRepeatGrid.add(generateDataCell(data.getVendor()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getModel()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getAlgorithm()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getCount()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getIsUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("导入的资产"),
                columnIndex.getAndIncrement(),rowIndex.getAndIncrement());
    }

    private void initServerStorageRepeat(){
        this.initGridHead(repeatExcelData.getServerStorages().size()*2,
                "重复资产","生产厂商","型号","操作系统版本","是否为虚拟设备","用途","数量","重要程度","是否测评","备注");
        AtomicInteger dataRowIndex = new AtomicInteger(1);
        repeatExcelData.getServerStorages().forEach(data->renderServerStorageRepeat(dataRowIndex,data));
    }
    private void renderServerStorageRepeat(AtomicInteger rowIndex,ServerStorageBO data){
        AtomicInteger columnIndex = new AtomicInteger(0);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getName()),
                columnIndex.getAndIncrement(),rowIndex.get(),1,2);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getVendor()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getModel()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getOsName()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getVirtual()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getCount()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getImportance()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(isUseToString(data.getSource().getIsUse())),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("已存在资产"),
                columnIndex.getAndIncrement(),rowIndex.get());
        ChangeListener<Toggle> callback = (observable, oldValue, newValue) -> {
            if(Objects.nonNull(newValue) && newValue instanceof RadioButton radioButton){
                String text = radioButton.getText();
                data.setRepeatCover(StringUtils.equals(text,"覆盖"));
            }
        };
        this.assetRepeatGrid.add(generateOptionCell(data.getRepeatCover(),callback),
                columnIndex.getAndSet(1),rowIndex.getAndIncrement(),1,2);

        this.assetRepeatGrid.add(generateDataCell(data.getVendor()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getModel()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getOsName()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getVirtual()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getCount()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getImportance()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getIsUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("导入的资产"),
                columnIndex.getAndIncrement(),rowIndex.getAndIncrement());
    }

    private void initNetworkSecurityRepeat(){
        this.initGridHead(repeatExcelData.getNetworkSecurity().size()*2,
                "重复资产","生产厂商","型号","用途","数量","重要程度","是否测评","备注");
        AtomicInteger dataRowIndex = new AtomicInteger(1);
        repeatExcelData.getNetworkSecurity().forEach(data->renderNetworkSecurityRepeat(dataRowIndex,data));
    }
    private void renderNetworkSecurityRepeat(AtomicInteger rowIndex,NetworkSecurityBO data){
        AtomicInteger columnIndex = new AtomicInteger(0);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getName()),
                columnIndex.getAndIncrement(),rowIndex.get(),1,2);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getVendor()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getModel()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getCount()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getImportance()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(isUseToString(data.getSource().getIsUse())),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("已存在资产"),
                columnIndex.getAndIncrement(),rowIndex.get());
        ChangeListener<Toggle> callback = (observable, oldValue, newValue) -> {
            if(Objects.nonNull(newValue) && newValue instanceof RadioButton radioButton){
                String text = radioButton.getText();
                data.setRepeatCover(StringUtils.equals(text,"覆盖"));
            }
        };
        this.assetRepeatGrid.add(generateOptionCell(data.getRepeatCover(),callback),
                columnIndex.getAndSet(1),rowIndex.getAndIncrement(),1,2);

        this.assetRepeatGrid.add(generateDataCell(data.getVendor()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getModel()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getCount()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getImportance()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getIsUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("导入的资产"),
                columnIndex.getAndIncrement(),rowIndex.getAndIncrement());
    }

    private void initDatabaseRepeat(){
        this.initGridHead(repeatExcelData.getDatabases().size()*2,
                "重复资产","版本","部署位置","主要功能","重要程度","是否测评","备注");
        AtomicInteger dataRowIndex = new AtomicInteger(1);
        repeatExcelData.getDatabases().forEach(data->renderDatabaseRepeat(dataRowIndex,data));
    }
    private void renderDatabaseRepeat(AtomicInteger rowIndex,DatabaseBO data){
        AtomicInteger columnIndex = new AtomicInteger(0);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getName()),
                columnIndex.getAndIncrement(),rowIndex.get(),1,2);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getVersion()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getLocation()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getFunction()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getImportance()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(isUseToString(data.getSource().getIsUse())),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("已存在资产"),
                columnIndex.getAndIncrement(),rowIndex.get());
        ChangeListener<Toggle> callback = (observable, oldValue, newValue) -> {
            if(Objects.nonNull(newValue) && newValue instanceof RadioButton radioButton){
                String text = radioButton.getText();
                data.setRepeatCover(StringUtils.equals(text,"覆盖"));
            }
        };
        this.assetRepeatGrid.add(generateOptionCell(data.getRepeatCover(),callback),
                columnIndex.getAndSet(1),rowIndex.getAndIncrement(),1,2);

        this.assetRepeatGrid.add(generateDataCell(data.getVersion()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getLocation()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getFunction()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getImportance()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getIsUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("导入的资产"),
                columnIndex.getAndIncrement(),rowIndex.getAndIncrement());
    }

    private void initKeyBusinessRepeat(){
        this.initGridHead(repeatExcelData.getKeyBusiness().size() * 2,
                "重复资产", "版本", "部署位置", "主要功能", "备注");
        AtomicInteger dataRowIndex = new AtomicInteger(1);
        repeatExcelData.getKeyBusiness().forEach(data->renderKeyBusinessRepeat(dataRowIndex,data));
    }
    private void renderKeyBusinessRepeat(AtomicInteger rowIndex,KeyBusinessBO data){
        AtomicInteger columnIndex = new AtomicInteger(0);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getName()),
                columnIndex.getAndIncrement(),rowIndex.get(),1,2);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getVersion()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getLocation()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getFunction()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(isUseToString(data.getSource().getIsUse())),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("已存在资产"),
                columnIndex.getAndIncrement(),rowIndex.get());
        ChangeListener<Toggle> callback = (observable, oldValue, newValue) -> {
            if(Objects.nonNull(newValue) && newValue instanceof RadioButton radioButton){
                String text = radioButton.getText();
                data.setRepeatCover(StringUtils.equals(text,"覆盖"));
            }
        };
        this.assetRepeatGrid.add(generateOptionCell(data.getRepeatCover(),callback),
                columnIndex.getAndSet(1),rowIndex.getAndIncrement(),1,2);

        this.assetRepeatGrid.add(generateDataCell(data.getVersion()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getLocation()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getFunction()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("导入的资产"),
                columnIndex.getAndIncrement(),rowIndex.getAndIncrement());
    }

    private void initSubBusinessRepeat(){
        this.initGridHead(repeatExcelData.getSubBusiness().size()*2,
                "重复资产","所属应用","安全需求","是否测评","备注");
        AtomicInteger dataRowIndex = new AtomicInteger(1);
        repeatExcelData.getSubBusiness().forEach(data->renderSubBusinessRepeat(dataRowIndex,data));
    }
    private void renderSubBusinessRepeat(AtomicInteger rowIndex,SubBusinessBO data){
        AtomicInteger columnIndex = new AtomicInteger(0);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getName()),
                columnIndex.getAndIncrement(),rowIndex.get(),1,2);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getOwnedApp()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getRequire()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(isUseToString(data.getSource().getIsUse())),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("已存在资产"),
                columnIndex.getAndIncrement(),rowIndex.get());
        ChangeListener<Toggle> callback = (observable, oldValue, newValue) -> {
            if(Objects.nonNull(newValue) && newValue instanceof RadioButton radioButton){
                String text = radioButton.getText();
                data.setRepeatCover(StringUtils.equals(text,"覆盖"));
            }
        };
        this.assetRepeatGrid.add(generateOptionCell(data.getRepeatCover(),callback),
                columnIndex.getAndSet(1),rowIndex.getAndIncrement(),1,2);

        this.assetRepeatGrid.add(generateDataCell(data.getOwnedApp()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getRequire()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getIsUse()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("导入的资产"),
                columnIndex.getAndIncrement(),rowIndex.getAndIncrement());
    }

    private void initKeyDataRepeat(){
        this.initGridHead(repeatExcelData.getKeyData().size()*2,
                "重复资产","描述","所属应用","存储位置","安全需求","备注");
        AtomicInteger dataRowIndex = new AtomicInteger(1);
        repeatExcelData.getKeyData().forEach(data->renderKeyDataRepeat(dataRowIndex,data));
    }
    private void renderKeyDataRepeat(AtomicInteger rowIndex,KeyDataBO data){
        AtomicInteger columnIndex = new AtomicInteger(0);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getData()),
                columnIndex.getAndIncrement(),rowIndex.get(),1,2);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getDescribe()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getOwnedApp()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getLocation()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getRequire()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("已存在资产"),
                columnIndex.getAndIncrement(),rowIndex.get());
        ChangeListener<Toggle> callback = (observable, oldValue, newValue) -> {
            if(Objects.nonNull(newValue) && newValue instanceof RadioButton radioButton){
                String text = radioButton.getText();
                data.setRepeatCover(StringUtils.equals(text,"覆盖"));
            }
        };
        this.assetRepeatGrid.add(generateOptionCell(data.getRepeatCover(),callback),
                columnIndex.getAndSet(1),rowIndex.getAndIncrement(),1,2);

        this.assetRepeatGrid.add(generateDataCell(data.getDescribe()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getOwnedApp()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getLocation()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getRequire()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("导入的资产"),
                columnIndex.getAndIncrement(),rowIndex.getAndIncrement());
    }

    private void initSecurityDocumentRepeat(){
        this.initGridHead(repeatExcelData.getSecurityDocuments().size()*2,
                "重复文档","主要内容");
        AtomicInteger dataRowIndex = new AtomicInteger(1);
        repeatExcelData.getSecurityDocuments().forEach(data->renderSecurityDocumentRepeat(dataRowIndex,data));
    }
    private void renderSecurityDocumentRepeat(AtomicInteger rowIndex,SecurityDocumentBO data){
        AtomicInteger columnIndex = new AtomicInteger(0);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getName()),
                columnIndex.getAndIncrement(),rowIndex.get(),1,2);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getContent()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("已存在资产"),
                columnIndex.getAndIncrement(),rowIndex.get());
        ChangeListener<Toggle> callback = (observable, oldValue, newValue) -> {
            if(Objects.nonNull(newValue) && newValue instanceof RadioButton radioButton){
                String text = radioButton.getText();
                data.setRepeatCover(StringUtils.equals(text,"覆盖"));
            }
        };
        this.assetRepeatGrid.add(generateOptionCell(data.getRepeatCover(),callback),
                columnIndex.getAndSet(1),rowIndex.getAndIncrement(),1,2);

        this.assetRepeatGrid.add(generateDataCell(data.getContent()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("导入的资产"),
                columnIndex.getAndIncrement(),rowIndex.getAndIncrement());
    }

    private void initPersonnelRepeat(){
        this.initGridHead(repeatExcelData.getPersonnel().size()*2,
                "重复姓名","岗位/角色","职责说明","联系方式");
        AtomicInteger dataRowIndex = new AtomicInteger(1);
        repeatExcelData.getPersonnel().forEach(data->renderPersonnelRepeat(dataRowIndex,data));
    }
    private void renderPersonnelRepeat(AtomicInteger rowIndex,PersonnelBO data){
        AtomicInteger columnIndex = new AtomicInteger(0);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getName()),
                columnIndex.getAndIncrement(),rowIndex.get(),1,2);
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getRole()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getSource().getTel()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("已存在资产"),
                columnIndex.getAndIncrement(),rowIndex.get());
        ChangeListener<Toggle> callback = (observable, oldValue, newValue) -> {
            if(Objects.nonNull(newValue) && newValue instanceof RadioButton radioButton){
                String text = radioButton.getText();
                data.setRepeatCover(StringUtils.equals(text,"覆盖"));
            }
        };
        this.assetRepeatGrid.add(generateOptionCell(data.getRepeatCover(),callback),
                columnIndex.getAndSet(1),rowIndex.getAndIncrement(),1,2);

        this.assetRepeatGrid.add(generateDataCell(data.getRole()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getDesc()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell(data.getTel()),
                columnIndex.getAndIncrement(),rowIndex.get());
        this.assetRepeatGrid.add(generateDataCell("导入的资产"),
                columnIndex.getAndIncrement(),rowIndex.getAndIncrement());
    }


    private void initGridHead(int dataRowSize,String... columns){
        this.initGridColumnConstraints(assetRepeatGrid,columns.length);
        this.initGridRowConstraints(assetRepeatGrid,dataRowSize);
        this.initGridTitleRow(assetRepeatGrid,columns);
    }

    private void initGridColumnConstraints(GridPane gridPane,int fieldCount){
        IntStream.range(0,fieldCount).forEach(number->{
            ColumnConstraints item = new ColumnConstraints();
            item.setHgrow(Priority.SOMETIMES);
            item.setMinWidth(80);
            gridPane.getColumnConstraints().add(item);
        });
        IntStream.of(1,2).forEach((number)->{
            ColumnConstraints fixedItem = new ColumnConstraints();
            fixedItem.setMinWidth(80);
            fixedItem.setPrefWidth(80);
            gridPane.getColumnConstraints().add(fixedItem);
        });
    }

    private void initGridRowConstraints(GridPane gridPane,int dataRowCount){
        RowConstraints titleRow = new RowConstraints();
        titleRow.setMinHeight(40);
        titleRow.setPrefHeight(40);
        titleRow.setVgrow(Priority.NEVER);
        gridPane.getRowConstraints().add(titleRow);
        IntStream.range(0,dataRowCount).forEach(number->{
            RowConstraints row = new RowConstraints();
            row.setMinHeight(30);
            row.setVgrow(Priority.SOMETIMES);
            gridPane.getRowConstraints().add(row);
        });
    }

    private void initGridTitleRow(GridPane gridPane,String... columns){
        int rowIndex=0;
        AtomicInteger columnIndex = new AtomicInteger(0);
        Stream.of(columns).forEach(title-> gridPane.add(generateHeadCell(title),columnIndex.getAndIncrement(),rowIndex));
        gridPane.add(generateHeadCell("来源"),columnIndex.getAndIncrement(),rowIndex);
        gridPane.add(generateHeadCell("操作"),columnIndex.getAndIncrement(),rowIndex);
    }

    private HBox generateHeadCell(String title){
        HBox hBox = new HBox();
        hBox.getStyleClass().add("grid-table-head");
        Label titleLbl = new Label(title);
        titleLbl.getStyleClass().add("label");
        hBox.getChildren().add(titleLbl);
        return hBox;
    }

    private VBox generateDataCell(String data){
        if(StringUtils.isEmpty(data)){
            data = "";
        }
        VBox vBox = new VBox();
        vBox.getStyleClass().add("grid-table-cell");
        Stream.of(data.split(BaseConstants.REGEX_WRAP_TEXT_SPLIT))
                .filter(StringUtils::isNotBlank)
                .forEach(text->{
                    Label label = new Label(text);
                    label.setWrapText(true);
                    label.setTooltip(new Tooltip(text));
                    vBox.getChildren().add(label);
                });
        return vBox;
    }

    private VBox generateOptionCell(Boolean isCover,ChangeListener<Toggle> callback){
        VBox vBox = new VBox();
        vBox.getStyleClass().add("grid-table-cell");
        vBox.setSpacing(10);
        ToggleGroup toggleGroup = new ToggleGroup();
        toggleGroup.selectedToggleProperty().addListener(callback);
        RadioButton coverRbx = new RadioButton("覆盖");
        coverRbx.setToggleGroup(toggleGroup);
        RadioButton breakRbx = new RadioButton("跳过");
        breakRbx.setToggleGroup(toggleGroup);
        if(Objects.nonNull(isCover)){
            coverRbx.setSelected(isCover);
            breakRbx.setSelected(!isCover);
        }
        vBox.getChildren().addAll(coverRbx,breakRbx);
        return vBox;
    }

    private String isUseToString(Boolean isUse){
        return Optional.ofNullable(isUse)
                .filter(d -> d)
                .map(d -> AssetConstants.USE_TAG)
                .orElse(AssetConstants.NOT_USE_TAG);
    }

    /**
     * 导入模式
     */
    private enum Mode{
        IMPORT,
        COVER
    }
}